import StoreBase, { IStoreBaseMeta } from '../../common/stores/StoreBase';
import {
  observable,
  autorun,
  action,
  computed,
  ObservableMap,
  isObservableArray,
} from 'mobx';
import {
  observablePromise,
  ObservableTempState,
  observableViewModel,
} from 'legions/store-utils';
import UiStoreBase from '../../common/stores/ui/UiStoreBase';
import { IResourceEvent, ITriggerEventPrams } from './even/resourceEvent';
import {
  InstanceProForm,
  IGroup,
} from 'legions-pro-design/es/LegionsProForm/interface';
import { InstanceProModal } from 'legions-pro-design/es/LegionsProModal/interface';
import { InstanceProTable } from 'legions-pro-design/es/LegionsProTable/interface';
import {
  LabelWithInputModel,
  LabelWithHLSelectModel,
  LabelWithDatePickerModel,
  LabelWithRangePickerModel,
  LabelWithRadioButtonModel,
  LabelWithUploadModel,
  LabelWithSwitchModel,
} from '../../common/interface/form';
import { I_FORM_PROPS, FORMSUBMITPROPERTY } from '../constants/consts';

import { MapperEntity } from 'json-mapper-object';
import { PropertyFormElementFormFields } from '../models/form/propertyFormElement';
import get from 'lodash/get';
import set from 'lodash/set';
import has from 'lodash/has';
// tslint:disable-next-line: no-empty-interface
import { message } from 'antd';
import { IAntdRule } from 'legions-pro-design/es/interface/antd';
import '../../main/assets/css/index.less';
import { PropertyKeyValueFormFields } from '../models/form/propertyFormModel';
import { IProConditions } from 'legions-pro-design/es/LegionsProConditions/ProConditionsUtils';
type IQuery = Array<IProConditions['componentModel']>;
import { inject, StoreModules } from 'legions/store';
import ProjectCommonStore from './projectCommonStore';
interface IContext {
  projectCommonApp: ProjectCommonStore;
}
/** 组件类型 */
export type ComponentType =
  | 'text'
  | 'select'
  | 'radioButton'
  | 'date'
  | 'daterange'
  | 'upload'
  | 'switch'
  | 'radio';
export type typeProFormModel =
  | InstanceType<typeof LabelWithInputModel>
  | InstanceType<typeof LabelWithHLSelectModel>
  | InstanceType<typeof LabelWithDatePickerModel>
  | InstanceType<typeof LabelWithRangePickerModel>
  | InstanceType<typeof LabelWithRadioButtonModel>
  | InstanceType<typeof LabelWithUploadModel>
  | InstanceType<typeof LabelWithSwitchModel>;

interface IEditComponentData {
  /** 组件类型 比如文本框，下拉，日期等组件类型 */
  type: ComponentType;
  /** 组件唯一key值，系统自动生成，无法更改 */
  keys: string;
  /** 随机生成，与Keys 对应 */
  randomUid: string,
  property: 'validationRuleReg'|string;
  propertyType?: IPropertyValue['type'];
}
interface IElementUidMapItem{
  uid: string;
  uuid: string;
  label: string;
  name: string;
}
interface ICode {
  /** 组件元素单个属性数据key,对应属性表单设置的组件元素name值 */
  key: string;
  value: string;
  /** 代码类型 表达式,函数, 特殊托管函数对象配置*/
  type: IPropertyValue['type'];
  /** 可执行代码字符串对象 */
  execast?: Object;
}

export interface IPropertyValue {
  /** 组件元素单个属性数据key,对应属性表单设置的组件元素name值 */
  key: string;
  value?: Object | string | number | boolean;
  /** 代码类型 表达式,函数, 特殊托管函数对象配置 */
  type: 'expression' | 'function' | 'autoQuery' | 'normal';
  /** 可执行代码字符串对象 */
  execast?: Object;
  /** 所属父级元素key */
  parent?: string;
}
export interface IPropertyData {
  /** 当前节点属性设置类型 */

  /*  currElementPropertys: Partial<Pick<ICode,'key' | 'type'>>[]; */
  /** 渲染元素信息集合 */
  renderElements: Partial<Pick<ICode, 'key'> & { isRender: boolean }>[];
  /** 表单组件属性设置数据结果集合 */
  propertyValue: IPropertyValue[];
  /** 表单临时数据存储区 */
  propertyValueTemp: IPropertyValue[];

  componentType?:ComponentType;
}
class FormViewModel {
  @inject(ProjectCommonStore)
  projectCommonApp:ProjectCommonStore= null;
  /** 表单分组列表信息 */
  @observable group: IGroup[] = observable.array([]);
  /** 表单布局方式，单列，两列，三列，四列 */
  @observable layout: 1|2|3|4 = 1;
  /** 表单尺寸 正常，迷你，紧凑 */
  @observable size: 'default' | 'small' | 'table' = 'default';
  /** 当前正在编辑的组件类型属性 */
  @observable editComponentData: IEditComponentData = {
    type: null,
    keys: '',
    property: void 0,
    randomUid:'',
  };
  /** 当前编辑器代码字符 */
  @observable codeValue = '';

  @observable codeEditorprop = {
    readOnly: false,
  };
  /** 当前编辑器代码字符转成可执行代码 */
  @observable execcodeast: object = null;
  /** 组件元素配置数据集 */
  @observable propertyData = observable.map<string, IPropertyData>();

  /** 在新增表单元素时，由于组件表单组件Uid 生成时机问题，而此时需要往组件元素label 区域绑定单击事件，这时需要先自动生成一个uid,然后待组件生成完成后，与之关联 */
  @observable elementUidMaps = observable.map<string,IElementUidMapItem>();
  
  @computed get computedElementUidMap() {
    const lit:IElementUidMapItem[] = [];
    for (let item of this.elementUidMaps.values()) {
      lit.push(item);
    }
    return lit;
  }
  /** 更新组件事件数据 用于事件数据Table组件展示 */
  @action updateEventData() {
    const data = [];
    ['onChange', 'onFocus', 'onBlur'].map(item => {
      const value = this.getPropertyDataValue(item);
      if (value) {
        data.push({ event: item, value });
      }
    });
    this.projectCommonApp.updateEventDataSource(data);
  }
  @action deleteEvent(key: string) {
    const items = this.propertyData.get(this.editComponentData.keys);
    const index = items.propertyValue.findIndex(e => e.key === key);
    if (index > -1) {
      items.propertyValue.splice(index, 1);
    }
  }
  /** 获取相应属性节点临时变量值 */
  @action getPropertyValueTemp(
    property: string,
    propertyType: IPropertyValue['type']
  ) {
    const codes = this.propertyData.get(this.editComponentData.keys);
    if (codes) {
      const item = codes.propertyValueTemp.find(
        item => item.key === property && item.type === propertyType
      );
      return item;
    }
    return null;
  }
  @action updatePropertyValueTemp(options: {
    value: string;
    execast?: Object;
    propertyType: IPropertyValue['type'];
    /** 组件元素单个属性数据key,对应属性表单设置的组件元素name值 */
    property: string;
    parent?: string;
  }) {
    const codes = this.propertyData.get(this.editComponentData.keys);
    if (codes) {
      const index = codes.propertyValueTemp.findIndex(
        item =>
          item.key === options.property && item.type === options.propertyType
      );
      if (index < 0) {
        codes.propertyValueTemp.push({
          key: options.property,
          value: options.value,
          type: options.propertyType,
          parent: get(options, 'parent') || null,
        });
      } else {
        codes.propertyValueTemp[index].value = options.value;
        codes.propertyValueTemp[index]['parent'] = get(options, 'parent');
        codes.propertyValueTemp[index].type = options.propertyType;
      }
    }
  }
  /** 获取相应属性节点变量值 */
  @action getPropertyValue(property: string) {
    const codes = this.propertyData.get(this.editComponentData.keys);
    if (codes) {
      const item = codes.propertyValue.find(item => item.key === property);
      return item;
    }
    return null;
  }
  @action updatePropertyValue(options: {
    value?: Object | number | boolean | string;
    propertyType: IPropertyValue['type'];
    /** 组件元素单个属性数据key,对应属性表单设置的组件元素name值 */
    property: string;
    /** 可执行代码字符串对象 */
    execast?: Object;
    /** 所属父级元素key */
    parent?: string;
  }) {
    const codes = this.propertyData.get(this.editComponentData.keys);
    if (codes) {
      const index = codes.propertyValue.findIndex(
        item => item.key === options.property
      );
      if (index < 0) {
        codes.propertyValue.push({
          key: options.property,
          type: options.propertyType,
          value: get(options, 'value', void 0),
          execast: options.execast || null,
          parent: options.parent || null,
        });
      } else {
        codes.propertyValue[index].type = options.propertyType;
        codes.propertyValue[index].value = get(options, 'value', void 0);
        codes.propertyValue[index].execast = options.execast || null;
        codes.propertyValue[index].parent = options.parent || null;
      }
    }
  }
  /** 查询PropertyData指定属性数据对象  */
  @action getPropertyDataValue(key: string) {
    const items = this.propertyData.get(this.editComponentData.keys);
    return items.propertyValue.find(e => e.key === key);
  }
}
@StoreModules
export default class ProjectFormPropertyStore extends UiStoreBase<IContext> {
  static meta: IStoreBaseMeta = {
    ...StoreBase.meta,
    /* className: 'ProjectFormPropertyStore', */
    eventScopes: [],
    contextTypes: {
      projectCommonApp:ProjectCommonStore,
    },
  };
  @observable formDraggerModel = {};
  /** 表单组件属性数据 */
  propertyFormationVM = observableViewModel<FormViewModel>(
    new FormViewModel()
  );
  /** 拖拽区域表单组件实例 */
  formPropertyDraggerRef: InstanceProForm = null;
  /** 表单属性设置侧边栏模态框实例 */
  formPropertyModalRef: InstanceProModal = null;
  /** 表单元素属性组件配置数据实例 */
  formProperyElementRef: InstanceProForm = null;
  /** 表单公共属性组件实例 */
  formProperyCommonRef: InstanceProForm = null;
  /** 代码编辑器模态框实例 */
  formPropertyCodeEditModalRef: InstanceProModal = null;

  /** 是否存在 */
  hasIAntdName(name: string) {
    const keys = this.propertyFormationVM.elementUidMaps.keys();
    let reulst = false;
    for (let key of keys) {
      const item = this.propertyFormationVM.elementUidMaps.get(key);
      if (
        item.name === name &&
        this.propertyFormationVM.editComponentData.keys !== item.uuid
      ) {
        reulst = true;
        break;
      }
    }
    return reulst;
  }
  /** 更新IAntdProps 对象信息*/
  updateIAntdProps(formFields: PropertyFormElementFormFields) {
    const iAntdProps = {};
    let nameValue = get(formFields, 'name.value');
    if (has(formFields, 'containerSpan')) {
      iAntdProps['span'] = get(formFields, 'containerSpan.value')
        ? Number(get(formFields, 'containerSpan.value'))
        : '';
    }
    if (has(formFields, 'name')) {
      iAntdProps['name'] = nameValue;
      iAntdProps['id'] = nameValue;
    }
    has(formFields, 'subGroup') &&
      (iAntdProps['groupId'] = Number(get(formFields, 'subGroup.value') || 1));
    has(formFields, 'placeholder') &&
      (iAntdProps['placeholder'] = get(
        formFields,
        'placeholder.value'
      ));
    return iAntdProps;
  }
  /** 更新组件元素公共信息部分数据 */
  updateCommonElementProps(
    formFields: PropertyFormElementFormFields,
    keys: string
  ) {
    const iformProps = {};
    has(formFields, 'maxLength') &&
      (iformProps['maxLength'] = get(formFields, 'maxLength.value'));
    has(formFields, 'labelCol') &&
      (iformProps['labelCol'] = {
        span: Number(get(formFields, 'labelCol.value')),
      });
    has(formFields, 'wrapperCol') &&
      (iformProps['wrapperCol'] = {
        span: Number(get(formFields, 'wrapperCol.value')),
      });
    if (has(formFields,'label')) {
      if (!get(formFields, 'label.value')) {
        this.formProperyElementRef.store.updateFormInputData(
          this.formProperyElementRef.uid,
          formFields
        );
      } else {
        iformProps['label'] = get(formFields, 'label.value');
      }
    }
    return iformProps;
  }
  /** 更新Input 输入配置数据信息 */
  updateInputElementProps(
    formFields: PropertyFormElementFormFields,
    keys: string
  ) {
    const inputPorps = {};
    const isDisabled = get(formFields, 'isDisabled.value');
    has(formFields, 'inputType') &&
      (inputPorps['type'] = get(formFields, 'inputType.value'));
    typeof isDisabled === 'boolean' &&
      (inputPorps['disabled'] = get(formFields, 'isDisabled.value'));
    return inputPorps;
  }
  /** 更新下拉选择器组件配置参数 */
  updateSelectElementProps(
    formFields: PropertyFormElementFormFields,
    keys: string
  ) {
    const selectPorps = {};
    const options = get(formFields, 'selectValue.value');
    const selectModel = get(formFields, 'selectModel.value');
    has(formFields, 'selectValue') && (selectPorps['options'] = options || []);
    if (has(formFields, 'selectModel') && selectModel === 'multiple') {
      selectPorps['mode'] = selectModel;
    }
    return selectPorps;
  }
  /** 更新上传组件配置参数 */
  updateUploadElementProps(
    formFields: PropertyFormElementFormFields,
    keys: string
  ) {
    const uploadPorps = {};
    const uploadIsDragger = get(formFields, 'uploadIsDragger.value');
    const uploadMultiple = get(formFields, 'uploadMultiple.value');
    const uploadShowFileList = get(formFields, 'uploadShowFileList.value');
    const uploadmaxFileCount = get(formFields, 'uploadmaxFileCount.value');
    const uploadshowFileListGroup = get(
      formFields,
      'uploadshowFileListGroup.value'
    );
    if (has(formFields, 'uploadIsDragger') && uploadIsDragger === true) {
      uploadPorps['isDragger'] = uploadIsDragger;
    }
    if (has(formFields, 'uploadMultiple') && uploadMultiple === true) {
      uploadPorps['multiple'] = uploadMultiple;
    }
    if (has(formFields, 'uploadShowFileList') && uploadShowFileList === true) {
      uploadPorps['showFileList'] = uploadShowFileList;
    }
    if (has(formFields, 'uploadmaxFileCount') && uploadmaxFileCount) {
      uploadPorps['maxFileCount'] = Number(uploadmaxFileCount);
    }
    if (has(formFields, 'uploadshowFileListGroup') && uploadshowFileListGroup) {
      uploadPorps['showFileListGroup'] = Number(uploadshowFileListGroup);
    }
    return uploadPorps;
  }
  /** 更新日期组件输入配置数据信息 */
  updateDateElementProps(
    formFields: PropertyFormElementFormFields,
    keys: string
  ) {
    const dateProps = {};
    has(formFields, 'format') &&
      (dateProps['format'] = get(formFields, 'format.value'));
    has(formFields, 'showTime') &&
      (dateProps['showTime'] = get(formFields, 'showTime.value'));
    return dateProps;
  }
  /** 更新单选组合输入配置数据信息 */
  updateRadioElementProps(
    formFields: PropertyFormElementFormFields,
    keys: string
  ) {
    const dateProps = {};
    const type = this.propertyFormationVM.editComponentData.type;
    const options = get(formFields, `${type}Value.value`);
    if (type === 'radioButton' || type === 'radio') {
      if (options && (isObservableArray(options) || Array.isArray(options))) {
        dateProps[type] = {
          options: options.map(item => {
            return { label: item.value, value: item.key, disabled: false };
          }),
        };
      }
    }
    return dateProps;
  }
  updateRules(formFields: PropertyFormElementFormFields, rules: IAntdRule[]) {}
  /** 更新必填验证规则数据 */
  updateRulesRequired(
    formFields: PropertyFormElementFormFields,
    rules: IAntdRule[],
    type: IAntdRule['type'] = 'string'
  ) {
    const isRequired = get(formFields, 'isRequired.value');
    const index = rules.findIndex(item => has(item, 'required'));
    if (index > -1) {
      if (isRequired === false) {
        rules.splice(index, 1);
      }
    } else {
      if (isRequired === true) {
        rules.push({
          message: '不能为空',
          required: true,
          // @ts-ignore
          trigger: 'blur,change',
          type,
        });
      }
    }
    return rules;
  }

  /** 添加表单元素 */
  @action addFormElement(
    key: string,
    label: string,
    type: ComponentType
  ) {
    this.propertyFormationVM.propertyData.set(key, {
      renderElements: [],
      propertyValue: [],
      propertyValueTemp: [],
      componentType:type,
    });
  }
  /** 获取指定组件属性表单值 */
  getProperyElementValue(field: string) {
    const formvalue: PropertyFormElementFormFields = get(
      this.formProperyElementRef,
      'viewModel.InputDataModel'
    ) as PropertyFormElementFormFields;
    return get(formvalue, `${field}.value`);
  }
  constructor(context: IContext) {
    super(context);
    this.initFormDraggerModel();
  }
  /** 初始化拖拽区域表单数据模型 */
  @action initFormDraggerModel() {
    for (let i = 0; i < 60; i++) {
      set(this.formDraggerModel, `element${i}`, { value: void 0 });
    }
  }
  @action onEvent(event: IResourceEvent<ITriggerEventPrams>) {}
}
